/**
 * 
 */
package com.maohi.software.tupuna.implementations;

import java.util.List;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.name.Names;
import com.google.inject.util.Modules;
import com.maohi.software.arii.Arii;
import com.maohi.software.arii.annotations.Extension;
import com.maohi.software.arii.mvc.events.ModelEvent;
import com.maohi.software.arii.mvc.events.UIEvent;
import com.maohi.software.arii.mvc.listeners.ModelListener;
import com.maohi.software.arii.mvc.listeners.UIListener;
import com.maohi.software.arii.utils.Keys;
import com.maohi.software.tupuna.Page;
import com.maohi.software.tupuna.constants.UIContext;
import com.maohi.software.tupuna.constants.UITypeEvent;
import com.maohi.software.tupuna.extensionpoints.BundleExtensionPoint;
import com.maohi.software.tupuna.interfaces.BundleApi;
import com.maohi.software.tupuna.interfaces.TupunaController;
import com.maohi.software.tupuna.interfaces.TupunaModel;
import com.maohi.software.tupuna.interfaces.TupunaUI;

/**
 * @author heifara
 * 
 */
public class DefaultTupunaController extends AbstractModule implements TupunaController, UIListener, ModelListener {

	private Injector injector;
	private final TupunaUI ui;
	private final TupunaModel model;

	@Inject
	@Extension("bundle")
	private List<BundleExtensionPoint> bundleExtensionPoints;

	@Inject
	public DefaultTupunaController(final TupunaUI aUI, final TupunaModel aModel) {
		this.ui = aUI;
		this.model = aModel;

		this.ui.addUIListener(this);
		this.model.addModelListener(this);
	}

	@Override
	protected void configure() {
		this.bind(TupunaController.class).toInstance(this);
		this.bind(TupunaModel.class).toInstance(this.model);
		this.bind(TupunaUI.class).toInstance(this.ui);
	}

	@Override
	public void dataChanged(ModelEvent aEvent) {
		// TODO Auto-generated method stub

	}

	@Override
	public void eventOccurred(UIEvent aEvent) {
		switch (aEvent.getType()) {
		case UITypeEvent.OPEN_BUNDLE:
			for (BundleExtensionPoint iBundleExtensionPoint : bundleExtensionPoints) {
				iBundleExtensionPoint.bundleOpened((BundleApi) aEvent.get(UIContext.BUNDLE_API));
			}
			break;

		case UITypeEvent.CHANGE_BUNDLE:
			break;

		default:
			break;
		}
	}

	@Override
	public <T> T getInstance(Class<T> aClass) {
		return injector.getInstance(aClass);
	}

	@Override
	public <T> T getInstance(Class<T> aClass, String aId) {
		return injector.getInstance(Key.get(aClass, Names.named(aId)));
	}

	@Override
	public <T> T getInstance(Key<T> aKey) {
		return injector.getInstance(aKey);
	}

	@Override
	public TupunaModel getModel() {
		return model;
	}

	@Override
	public Page getPage(String aTitle) {
		return this.ui.getPage(aTitle);
	}

	@Override
	public TupunaUI getUi() {
		return ui;
	}

	@Override
	public Page newPage() {
		final Page iPage = this.ui.newPage();
		return iPage;
	}

	@Override
	public void start() {
		List<Module> iModules = Arii.getInstance(Keys.getListModule());
		injector = Guice.createInjector(Modules.override(iModules).with(this));

		this.ui.openUI(this);
	}

	@Override
	public void stop() {
	}

}
